技术干货:解密最受欢迎的开源 Serverless 框架弹性技术实现
基于请求的自动弹性 KPA
Cloud Native
基于 CPU 或者 Memory 的弹性,有时候并不能完全反映业务的真实使用情况,而基于并发数或者每秒处理请求数 (QPS/RPS),对于 web 服务来说更能直接反映服务性能,Knative 提供了基于请求的自动弹性能力。要获得当前服务的请求数,Knative Serving 为每个 Pod 注入 QUEUE 代理容器 (queue-proxy),该容器负责收集用户容器并发数 (concurrency) 或请求数 (rps) 指标。Autoscaler 定时获取这些指标之后,会根据相应的算法,调整 Deployment 的 Pod 数量,从而实现基于请求的自动扩缩容。
图片来源:https://knative.dev/docs/serving/request-flow/
基于请求数的弹性算法
POD数=并发请求总数/(Pod最大并发数*目标使用率)
例如服务中 Pod 最大并发数设置了 10,这时候如果接收到了 100 个并发请求,目标使用率设置为 0.7,那么 Autoscaler 就会创建了 15 个 POD(100/(0.7*10) 约等于 15)。
缩容到 0 的实现机制
应对突发流量
突发流量下如何快速弹资源
突发流量下如何避免 Pod 被打爆
减少冷启动的一些技巧
延迟缩容
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/scale-down-delay: ""60s"
autoscaling.knative.dev/scale-to-zero-pod-retention-period: "1m5s"
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:73fbdd56
调低目标使用率,实现资源预热
Knative 中提供了目标阈值使用率的配置。通过调小该值可以提前扩容超过实际需要使用量的 Pod 数,在请求达到目标并发数之前进行扩容,间接的可以做到资源预热。例如,如果 containerConcurrency 设置为 10,目标利用率值设置为 70(百分比),则当所有现有 Pod 的平均并发请求数达到 7 时,Autoscaler 将创建一个新 Pod。因为 Pod 从创建到 Ready 需要一定的时间,通过调低目标利用率值可以做到提前扩容 Pod,从而减少冷启动导致的响应延迟等问题。
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/target-utilization-percentage: "70"
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/knative-sample/helloworld-go:73fbdd56
配置 KPA
全局模式
kubectl -n knative-serving get cm config-autoscaler
apiVersion: v1
kind: ConfigMap
metadata:
name: config-autoscaler
namespace: knative-serving
data:
container-concurrency-target-default: "100"
container-concurrency-target-percentage: "70"
requests-per-second-target-default: "200"
target-burst-capacity: "211"
stable-window: "60s"
panic-window-percentage: "10.0"
panic-threshold-percentage: "200.0"
max-scale-up-rate: "1000.0"
max-scale-down-rate: "2.0"
enable-scale-to-zero: "true"
scale-to-zero-grace-period: "30s"
scale-to-zero-pod-retention-period: "0s"
pod-autoscaler-class: "kpa.autoscaling.knative.dev"
activator-capacity: "100.0"
initial-scale: "1"
allow-zero-initial-scale: "false"
min-scale: "0"
max-scale: "0"
scale-down-delay: "0s"
参数说明:
Revision 版本模式
指标类型
每个 revision 指标注解:autoscaling.knative.dev/metric 支持的指标:"concurrency","rps","cpu","memory"以及其它自定义指标 默认指标:"concurrency"
目标阈值
autoscaling.knative.dev/target 默认值:"100"
pod 缩容到 0 保留期
autoscaling.knative.dev/scale-to-zero-pod-retention-period
目标使用率
autoscaling.knative.dev/target-utilization-percentage
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/metric: "concurrency"
autoscaling.knative.dev/target: "50"
autoscaling.knative.dev/scale-to-zero-pod-retention-period: "1m5s"
autoscaling.knative.dev/target-utilization-percentage: "80"
对 HPA 的支持
Cloud Native
对于 K8s HPA, Knative 也提供天然的配置支持,可以在 Knative 使用基于 CPU 或者 Memory 的自动弹性能力。
基于 CPU 弹性配置
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/class: "hpa.autoscaling.knative.dev"
autoscaling.knative.dev/metric: "cpu"
基于 Memory 的弹性配置
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/class: "hpa.autoscaling.knative.dev"
autoscaling.knative.dev/metric: "memory"
弹性能力增强
Cloud Native
Knative 提供了灵活的插件机制(pod-autoscaler-class),可以支持不同的弹性策略。阿里云容器服务 Knative 当前支持的弹性插件包括:kpa、hpa、精准弹性扩缩容 mpa 以及 具有预测能力的 ahpa。
保留资源池
ECS 与 ECI 混用。如果希望常态情况下使用 ECS 资源,突发流量使用 ECI, 那么我们可以通过保留资源池来实现。如单个 Pod 处理的并发 10,保留资源池 Pod 数为 5,那么常态下通过 ECS 资源可以应对不超过 50 的并发请求。如果并发数超过 50,那么 Knative 就会扩容新的 Pod 数来满足需求,新扩容出来的资源使用 ECI。
资源预热。对于完全使用 ECI 的场景,也可以通过保留资源池实现资源预热。当在业务波谷时使用保留实例替换默认的计算型实例,当第一个请求来临时使用保留实例提供服务,同时也会触发默认规格实例的扩容。当默认规格实例扩容完成以后所有新请求就会都转发到默认规格上,同时保留实例则不会接受新的请求,并且等保留实例所有接收到的请求处理完成以后就会被下线。通过这种无缝替换的方式实现了成本和效率的平衡,即降低了常驻实例的成本又不会有显著的冷启动时长。
精准弹性扩缩容
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: helloworld-go
spec:
template:
metadata:
annotations:
autoscaling.knative.dev/class: mpa.autoscaling.knative.dev
autoscaling.knative.dev/max-scale: '20'
spec:
containerConcurrency: 5
containers:
- image: registry-vpc.cn-beijing.aliyuncs.com/knative-sample/helloworld-go:73fbdd56
env:
- name: TARGET
value: "Knative"
参数说明:
弹性预测 AHPA
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: autoscale-go
namespace: default
spec:
template:
metadata:
labels:
app: autoscale-go
annotations:
autoscaling.knative.dev/class: ahpa.autoscaling.knative.dev
autoscaling.knative.dev/target: "10"
autoscaling.knative.dev/metric: "rps"
autoscaling.knative.dev/minScale: "1"
autoscaling.knative.dev/maxScale: "30"
autoscaling.alibabacloud.com/scaleStrategy: "observer"
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/knative-sample/autoscale-go:0.1
参数说明:
|
小结
Cloud Native
本文从 Knative 典型弹性实现 KPA 出发进行介绍,包括如何实现基于请求的自动弹性、缩容到 0、应对突发流量以及我们在 Knative 弹性功能上的扩展增强,包括保留资源池,精准弹性以及弹性预测能力。
这里我们也提供了一个在 AIGC 场景中,使用 Knative 的体验活动,欢迎参与:快来解锁你家萌宠专属 AI 形象!活动时间:2023/08/24-09/24。
快来解锁你家萌宠专属 AI 形象!
https://developer.aliyun.com/adc/series/petsai#J_2264716120
点击阅读原文,立即解锁你家萌宠专属 AI 形象